package swardToOffer.struct_4_tree;

import java.util.Arrays;

/**
 * @Author ChanZany
 * @Date 2021/5/19 19:40
 * @Version 1.0
 * 面试题7：重建二叉树
 * 题目：输入某二叉树的前序遍历和中序遍历的结果，请重建出该二叉树。假设输
 * 入的前序遍历和中序遍历的结果中都不含重复的数字。
 * 例如输入前序遍历序列{1, 2, 4, 7, 3, 5, 6, 8}和中序遍历序列{4, 7, 2, 1, 5, 3, 8, 6}，则重建出
 * 图2.6所示的二叉树并输出它的头结点。
 * 思路：前序遍历的第一个元素为根节点，中序遍历序列被根节点分为左子树和右子树
 */
public class RebuildBinaryTree {
    private TreeNode rebuild(int[] preOrder, int[] inOrder) {
        if (preOrder.length <= 0) return null;
        //得到root节点
        int rootVal = preOrder[0];
        int rootIndexInorder = getIndex(rootVal, inOrder);
        //划分左子树和右子树
        int[] preOrderLeft = Arrays.copyOfRange(preOrder, 1, rootIndexInorder + 1);
        int[] inOrderLeft = Arrays.copyOfRange(inOrder, 0, rootIndexInorder);
        int[] preOrderRight = Arrays.copyOfRange(preOrder, rootIndexInorder + 1, preOrder.length);
        int[] inOrderRight = Arrays.copyOfRange(inOrder, rootIndexInorder + 1, inOrder.length);

        //构建左子树和右子树
        TreeNode root = new TreeNode(rootVal);
        root.left = rebuild(preOrderLeft, inOrderLeft);
        root.right = rebuild(preOrderRight, inOrderRight);
        return root;
    }

    private int getIndex(int rootVal, int[] inOrder) {
        for (int i = 0; i < inOrder.length; i++) {
            if (inOrder[i] == rootVal) return i;
        }
        return -1;
    }

    public static void main(String[] args) {
        int[] preOrder = {1, 2, 4, 7, 3, 5, 6, 8};
        int[] inOrder = {4, 7, 2, 1, 5, 3, 8, 6};
        RebuildBinaryTree Main = new RebuildBinaryTree();
        TreeNode rebuild = Main.rebuild(preOrder, inOrder);
        TreeUtil.preOrder(rebuild);
        System.out.println("---------------------------");
        TreeUtil.LevelTraversal(rebuild);
    }


}
